home *** CD-ROM | disk | FTP | other *** search
/ Risc World 3 / Risc World 3.iso / SOFTWARE / ISSUE6 / PD / PDF / pdf / c++ / Find < prev    next >
Text File  |  2003-02-14  |  8KB  |  288 lines

  1. //--------------------------------------------------------------------------
  2. //
  3. //   Copyright (c) 2002, Colin Granville
  4. //
  5. //   All rights reserved.
  6. //
  7. //   Redistribution and use in source and binary forms, with or
  8. //   without modification, are permitted provided that the following 
  9. //   conditions are met:
  10. //
  11. //      * Redistributions of source code must retain the above copyright 
  12. //        notice, this list of conditions and the following disclaimer.
  13. //
  14. //      * Redistributions in binary form must reproduce the above 
  15. //        copyright notice, this list of conditions and the following 
  16. //        disclaimer in the documentation and/or other materials 
  17. //        provided with the distribution.
  18. //
  19. //      * The name Colin Granville may not be used to endorse or promote 
  20. //        products derived from this software without specific prior 
  21. //        written permission.
  22. //
  23. //   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  24. //   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  25. //   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
  26. //   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
  27. //   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
  28. //   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
  29. //   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  30. //   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  31. //   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  32. //   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  33. //   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
  34. //   OF THE POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. //--------------------------------------------------------------------------
  37.  
  38. #include "Find.h"
  39. #include "DocView.h"
  40. #include "GuiWindow.h"
  41. #include "GuiGadget.h"
  42. #include "GuiTargets.h"
  43. #include "TextOutputDev.h"
  44. #include "GfxState.h"
  45. #include "UserEvents.h"
  46. #include "Document.h"
  47. #include "guilib:gfx.h"
  48. #include "strstream.h"
  49.  
  50. class TextOutputDevice : public TextOutputDev
  51. {
  52.   public:
  53.     TextOutputDevice();
  54.     virtual ~TextOutputDevice() {};
  55.  
  56.     double getHeight()  {return height;}
  57.     virtual void startPage(int pageNum, GfxState *state);
  58.   private:
  59.     double height;
  60. };
  61.  
  62. //*************************************************************************
  63.  
  64. TextOutputDevice::TextOutputDevice()
  65.  : TextOutputDev(0,0,0,0),
  66.    height(0)
  67. }
  68.  
  69. //*************************************************************************
  70.  
  71. void TextOutputDevice::startPage(int pageNum, GfxState *state)
  72. {
  73.   setDefaultCTM(state->getCTM());
  74.   GuiBBox bounds;
  75.   cvtUserToDev(state->getX1(),state->getY1(),&bounds.xmin,&bounds.ymin);
  76.   cvtUserToDev(state->getX2(),state->getY2(),&bounds.xmax,&bounds.ymax);
  77.   height=(double)(bounds.ymin-bounds.ymax);
  78.   TextOutputDev::startPage(pageNum,state);
  79. }
  80.  
  81. //*************************************************************************
  82. //*************************************************************************
  83. //*************************************************************************
  84.  
  85. class Find
  86. {
  87.   public: 
  88.     Find();
  89.     ~Find();
  90.     
  91.     void aboutToBeShown(DocView& view);
  92.     void viewClosed(DocView& view);
  93.  
  94.   private:
  95.     GuiWindow         window;
  96.     GuiWritableField  text;
  97.     GuiOptionButton   fromStart;
  98.     GuiButton         notFound;
  99.  
  100.     GuiWindow         nextWindow;
  101.     GuiButton         nextStatus;
  102.     GuiActionButton   nextButton;
  103.  
  104.     DocView*          view;
  105.     TextOutputDevice  outDev;
  106.     int               page;
  107.     string            searchString;
  108.     bool              top;
  109.     double            fromx,fromy;
  110.  
  111.     void showPageStatus();
  112.  
  113.     GUI_DECLARE_EVENT_TARGETS(Find);
  114.  
  115.     GuiNullTarget  nullEventTarget;
  116.     void nullEvent();
  117.  
  118.     GuiNullTarget  nextHiddenTarget;
  119.     void nextHidden();
  120.  
  121.     GuiToolboxTarget doFindTarget;
  122.     Claim doFind(GuiToolboxEvent&,const GuiIdBlock&);
  123.  
  124.     GuiToolboxTarget findNextTarget;
  125.     Claim findNext(GuiToolboxEvent&,const GuiIdBlock&);
  126.  
  127. };
  128.  
  129. //*************************************************************************
  130.  
  131. Find::Find()
  132.  : window("Find"),
  133.    text(window,1),
  134.    fromStart(window,2),
  135.    notFound(window,5),
  136.    nextWindow("FindNext"),
  137.    nextStatus(nextWindow,5),
  138.    nextButton(nextWindow,2),
  139.    view(0),
  140.    doFindTarget(&window,User_Find,this,Find::doFind),
  141.    findNextTarget(&nextWindow,User_FindNext,this,Find::findNext)
  142. {
  143. }
  144.  
  145. //*************************************************************************
  146.  
  147. Find::~Find() {}
  148.  
  149. //*************************************************************************
  150.  
  151. void Find::aboutToBeShown(DocView& v)
  152. {
  153.   view=&v;
  154.   notFound.setValue("");
  155.   fromStart.set(0);
  156. }
  157.  
  158. //*************************************************************************
  159.  
  160. void Find::viewClosed(DocView& v)
  161. {
  162.   if (&v==view)
  163.   {
  164.     view=0;
  165.     window.hide();
  166.     nextWindow.hide();
  167.   }
  168. }
  169.  
  170. //*************************************************************************
  171.  
  172. Claim Find::doFind(GuiToolboxEvent&,const GuiIdBlock&)
  173. {
  174.   searchString=text.getValue();
  175.   if (searchString.size()==0) return CLAIM;
  176.  
  177.   page=(fromStart.isOn()? 1 : view->getPage());
  178.   nullEventTarget(this,Find::nullEvent);
  179.   nextHiddenTarget(this,Find::nextHidden);
  180.   nextWindow.showAsMenuCentred(window,&window);
  181.   nextButton.fade(1);
  182.   showPageStatus();
  183.   top=1;
  184.   return CLAIM;
  185. }
  186.  
  187. //*************************************************************************
  188.  
  189. void Find::nextHidden()
  190. {
  191.   if (!nextWindow.isShowing())
  192.   {
  193.     nextHiddenTarget.destroy();
  194.     nullEventTarget.destroy();
  195.     if (view) view->clearHighlight();
  196.   }
  197. }
  198.  
  199. //*************************************************************************
  200.  
  201. void Find::nullEvent()
  202. {
  203.   int pageCount=view->getDocument().getPageCount();
  204.   if (view==0 ||  (page<1 || page>pageCount))
  205.   {
  206.     nullEventTarget.destroy();
  207.     return;
  208.   }
  209.  
  210.   if (top) view->getDocument().getPage(page,&outDev,DrawOutputDevice::DPI,0);
  211.  
  212.   Unicode* unicode=new Unicode[searchString.size()];
  213.   int i;
  214.   if (!unicode)
  215.   {
  216.     nullEventTarget.destroy();
  217.     return;
  218.   }
  219.   unsigned char*s=(unsigned char*)searchString.c_str();
  220.   for (i=0;i<searchString.size();i++) unicode[i]=s[i];
  221.  
  222.   double xmax,ymax;
  223.   if (outDev.findText(unicode,searchString.size(),
  224.                        top,1,&fromx,&fromy,&xmax,&ymax))
  225.   {
  226.     HighlightBBox box;
  227.     box.xmin=fromx;
  228.     box.ymin=outDev.getHeight()-ymax;
  229.     box.xmax=xmax;
  230.     box.ymax=outDev.getHeight()-fromy;
  231.     fromx=xmax;
  232.     fromy=ymax;
  233.     top=0;
  234.     nullEventTarget.destroy();
  235.     nextStatus.setValue("Found");
  236.     nextButton.fade(0);
  237.     view->setHighlight(page,box);
  238.   }
  239.   else 
  240.   {
  241.     page++;
  242.     top=1;
  243.     if (page>pageCount)
  244.     {
  245.       nextStatus.setValue("Not Found");
  246.     }
  247.     else
  248.     {
  249.       showPageStatus();
  250.     }
  251.   }
  252.   delete [] unicode;
  253. }
  254.  
  255. //*************************************************************************
  256.  
  257. void Find::showPageStatus()
  258. {
  259.   char buf[32];
  260.   ostrstream out(buf,sizeof(buf));
  261.   out << "Searching page: " << page;
  262.   nextStatus.setValue(out.str());
  263. }
  264.  
  265. //*************************************************************************
  266.  
  267. Claim Find::findNext(GuiToolboxEvent&,const GuiIdBlock&)
  268. {
  269.   if (view)
  270.   {
  271.     nullEventTarget(this,Find::nullEvent);
  272.     nextButton.fade(1);
  273.   }
  274.   return CLAIM;
  275. }
  276.  
  277. //*************************************************************************
  278.  
  279. void find(DocView& view,bool ViewClosed)
  280. {
  281.   static Find f;
  282.   if (ViewClosed)
  283.     f.viewClosed(view);
  284.   else
  285.     f.aboutToBeShown(view);
  286. }
  287.